#include "Avalon/ServiceLocator/ServiceLocator.hpp"
#include <cryptopp/hex.h>
#include <cryptopp/osrng.h>
#include <cryptopp/sha.h>

using namespace Avalon;
using namespace Avalon::ServiceLocator;
using namespace CryptoPP;
using namespace std;

namespace {
  AutoSeededRandomPool randomPool;
}

string Avalon::ServiceLocator::GenerateSessionId() {
  char randomBytes[SESSION_ID_LENGTH];
  randomPool.GenerateBlock(reinterpret_cast<byte*>(randomBytes),
    SESSION_ID_LENGTH);
  for(int i = 0; i < SESSION_ID_LENGTH; ++i) {
    randomBytes[i] = (static_cast<unsigned char>(randomBytes[i]) % 26) + 'a';
  }
  return string(randomBytes, SESSION_ID_LENGTH);
}

string Avalon::ServiceLocator::ComputeSHA(const string& message) {
  string baseMessage = message;
  SHA sha;
  byte digest[SHA::DIGESTSIZE];
  sha.CalculateDigest(digest,
    reinterpret_cast<const byte*>(baseMessage.c_str()),
    baseMessage.length());
  HexEncoder encoder;
  string output;
  encoder.Attach(new StringSink(output));
  encoder.Put(digest, sizeof(digest));
  encoder.MessageEnd();
  return output;
}

unsigned int Avalon::ServiceLocator::GenerateEncryptionKey() {
  AutoSeededRandomPool randomPool;
  unsigned int randomBytes;
  randomPool.GenerateBlock(reinterpret_cast<byte*>(&randomBytes),
    sizeof(randomBytes));
  return randomBytes;
}
